/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.zhuangfei.ohos_timetableview.slice;

import com.zhuangfei.ohos_timetableview.ResourceTable;
import com.zhuangfei.ohos_timetableview.base.BaseAbilitySlice;
import com.zhuangfei.ohos_timetableview.bean.WeekChooseBean;
import com.zhuangfei.ohos_timetableview.dialog.ChooseWeekDialog;
import com.zhuangfei.ohos_timetableview.dialog.ToastViewDialog;
import com.zhuangfei.ohos_timetableview.model.MySubject;
import com.zhuangfei.ohos_timetableview.model.SubjectRepertory;
import com.zhuangfei.ohos_timetableview.spinner.MaterialSpinner;
import com.zhuangfei.timetable.TimetableView;
import com.zhuangfei.timetable.listener.ISchedule;
import com.zhuangfei.timetable.listener.IWeekView;
import com.zhuangfei.timetable.listener.OnSlideBuildAdapter;
import com.zhuangfei.timetable.model.Schedule;
import com.zhuangfei.timetable.view.WeekView;

import ohos.aafwk.content.Intent;
import ohos.agp.components.Component;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.Text;
import ohos.agp.utils.Color;

import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;

/**
 * BaseFuncSlice
 *
 * @since 2021-03-29
 */
public class BaseFuncSlice extends BaseAbilitySlice implements Component.ClickedListener {
    private static final String[] SPIN_MUNE = {"月份宽度增大", "月份宽度恢复", "隐藏周末", "显示周末",
            "添加一门课程", "删除一门课程", "隐藏非本周课程", "显示非本周课程", "最大节次8节",
            "最大节次10节", "最大节次12节", "显示节次时间", "隐藏节次时间", "显示周次选择", "隐藏周次选择"};
    /**
     * 控件
     */
    TimetableView mTimetableView;
    WeekView mWeekView;
    DirectionalLayout layout;
    Text titleTextView;
    List<MySubject> mySubjects;
    Intent intents;
    /**
     * 记录切换的周次，不一定是当前周
     */
    int target = -1;


    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_base_func);
        initViews();
        intents = intent;
    }

    private void initViews() {
        mTimetableView = (TimetableView) findComponentById(ResourceTable.Id_id_timetableView);
        mWeekView = (WeekView) findComponentById(ResourceTable.Id_id_weekview);
        titleTextView = (Text) findComponentById(ResourceTable.Id_id_title);
        layout = (DirectionalLayout) findComponentById(ResourceTable.Id_id_layout);
        MaterialSpinner spinner = (MaterialSpinner) findComponentById(ResourceTable.Id_id_more);

        mySubjects = SubjectRepertory.loadDefaultSubjects2();
        mySubjects.addAll(SubjectRepertory.loadDefaultSubjects());

        layout.setClickedListener(this);

        spinner.setOnItemSelectedListener(new MaterialSpinner.OnItemSelectedListener<String>() {
            @Override
            public void onItemSelected(MaterialSpinner view, int position, long id, String item) {
                selectLayout(position);
                spinner.setShowFalse();

            }
        });
        spinner.setItems(SPIN_MUNE);
        spinner.setOnNothingSelectedListener(new MaterialSpinner.OnNothingSelectedListener() {

            @Override
            public void onNothingSelected(MaterialSpinner spinner) {
                spinner.setShowFalse();
            }
        });
        initTimetableView();
    }

    @Override
    public void onActive() {
        super.onActive();
        mTimetableView.onDateBuildListener()
                .onHighLight();
    }

    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);
    }

    /**
     * 初始化课程控件
     */
    private void initTimetableView() {
        /**
         * 获取控件
         */
        mWeekView = (WeekView) findComponentById(ResourceTable.Id_id_weekview);
        mTimetableView = (TimetableView) findComponentById(ResourceTable.Id_id_timetableView);
        /**
         * 设置周次选择属性
         */
        mWeekView.source(mySubjects)
                .curWeek(1)
                .callback(new IWeekView.OnWeekItemClickedListener() {
                    @Override
                    public void onWeekClicked(int week) {
                        int cur = mTimetableView.curWeek();
                        /**
                         * 更新切换后的日期，从当前周cur->切换的周week
                         */
                        mTimetableView.onDateBuildListener()
                                .onUpdateDate(cur, week);
                        mTimetableView.changeWeekOnly(week);
                    }
                })
                .callback(new IWeekView.OnWeekLeftClickedListener() {
                    @Override
                    public void onWeekLeftClicked() {
                        onWeekLeftLayoutClicked();
                    }
                })
                .isShow(false)
                .showView();

        mTimetableView.source(mySubjects)
                .curWeek(1)
                .curTerm("大三下学期")
                .maxSlideItem(10)
                .monthWidthDp(80)
                .callback(new ISchedule.OnItemClickListener() {
                    @Override
                    public void onItemClick(Component v, List<Schedule> scheduleList) {
                        display(scheduleList);
                    }
                })
                .callback(new ISchedule.OnItemLongClickListener() {
                    @Override
                    public void onLongClick(Component v, int day, int start) {
                        ToastViewDialog.toast(BaseFuncSlice.this, "长按:周" + day + ",第" + start + "节");
                    }
                })
                .callback(new ISchedule.OnWeekChangedListener() {
                    @Override
                    public void onWeekChanged(int curWeek) {
                        titleTextView.setText("第" + curWeek + "周");
                    }
                })
                /**
                 * 旗标布局点击监听
                 */
                .callback(new ISchedule.OnFlaglayoutClickListener() {
                    @Override
                    public void onFlaglayoutClick(int day, int start) {
                        BaseFuncSlice.this.getUITaskDispatcher().asyncDispatch(() -> {
                            mTimetableView.hideFlaglayout();
                        });
                        ToastViewDialog.toast(BaseFuncSlice.this, "点击了旗标:周" + (day + 1) + ",第" + start + "节");
                    }
                })
                .showView();
    }

    /**
     * 周次选择布局的左侧被点击时回调<br/>
     * 对话框修改当前周次
     */
    protected void onWeekLeftLayoutClicked() {
        final ArrayList<WeekChooseBean> items = new ArrayList<>();
        int itemCount = mWeekView.itemCount();
        for (int i = 0; i < itemCount; i++) {
            WeekChooseBean bean = new WeekChooseBean();
            bean.setWeek("第" + (i + 1) + "周");
            if (i == 0) {
                bean.setSelect(true);
            } else {
                bean.setSelect(false);
            }
            items.add(bean);
        }
        target = -1;

        ChooseWeekDialog chooseWeekDialog = new ChooseWeekDialog(this, mTimetableView.curWeek() - 1);
        chooseWeekDialog.setTitle("设置当前周");
        chooseWeekDialog.setData(items);
        chooseWeekDialog.setmConfimClickListen(new ChooseWeekDialog.ConfimClickListen() {
            @Override
            public void onConfimClick(int index) {
                target = index;
                if (target != -1) {
                    mWeekView.curWeek(target + 1).updateView();
                    mTimetableView.changeWeekForce(target + 1);
                }
            }
        });
        chooseWeekDialog.setCancleButton(new ChooseWeekDialog.CancleClickListen() {
            @Override
            public void onCancleClick() {
            }
        });
        chooseWeekDialog.show();
    }

    /**
     * 显示内容
     *
     * @param beans
     */
    protected void display(List<Schedule> beans) {
        StringBuffer s = new StringBuffer();
        for (Schedule bean : beans) {
            s.append(bean.getName() + "," + bean.getWeekList().toString() + ","
                    + bean.getStart() + "," + bean.getStep() + "\n");
        }
        String str = s.toString();
        ToastViewDialog.toast(this, str);
    }


    private void selectLayout(int position) {
        switch (position) {
            case 0:
                setMonthWidth();
                break;
            case 1:
                resetMonthWidth();
                break;
            case 2:
                hideWeekends();
                break;
            case 3:
                showWeekends();
                break;
            case 4:
                addSubject();
                break;
            case 5:
                deleteSubject();
                break;
            case 6:
                hideNonThisWeek();
                break;
            case 7:
                showNonThisWeek();
                break;
            case 8:
                setMaxItem(8);
                break;
            case 9:
                setMaxItem(10);
                break;
            case 10:
                setMaxItem(12);
                break;
            case 11:
                showTime();
                break;
            case 12:
                hideTime();
                break;
            case 13:
                showWeekView();
                break;
            case 14:
                hideWeekView();
                break;
            default:
                break;
        }
    }

    @Override
    public void onClick(Component component) {
        switch (component.getId()) {
            case ResourceTable.Id_id_layout:
                /**
                 * 如果周次选择已经显示了，那么将它隐藏，更新课程、日期
                 * 否则，显示
                 */
                if (mWeekView.isShowing()) {
                    mWeekView.isShow(false);
                    titleTextView.setTextColor(new Color(Color.rgb(19, 176, 241)));
                    int cur = mTimetableView.curWeek();
                    mTimetableView.onDateBuildListener()
                            .onUpdateDate(cur, cur);
                    mTimetableView.changeWeekOnly(cur);
                } else {
                    mWeekView.isShow(true);
                    titleTextView.setTextColor(Color.RED);
                }
                break;
            default:
                break;
        }
    }

    /**
     * 删除课程
     * 内部使用集合维护课程数据，操作集合的方法来操作它即可
     * 最后更新一下视图（全局更新）
     */
    protected void deleteSubject() {
        int size = mTimetableView.dataSource().size();
        int pos = (int) (new SecureRandom().nextDouble() * size);
        if (size > 0) {
            mTimetableView.dataSource().remove(pos);
            mTimetableView.updateView();
        }
    }

    /**
     * 添加课程
     * 内部使用集合维护课程数据，操作集合的方法来操作它即可
     * 最后更新一下视图（全局更新）
     */
    protected void addSubject() {
        List<Schedule> dataSource = mTimetableView.dataSource();
        int size = dataSource.size();
        if (size > 0) {
            Schedule schedule = dataSource.get(0);
            dataSource.add(schedule);
            mTimetableView.updateView();
        }
    }

    /**
     * 隐藏非本周课程
     * 修改了内容的显示，所以必须更新全部（性能不高）
     * 建议：在初始化时设置该属性
     * <p>
     * updateView()被调用后，会重新构建课程，课程会回到当前周
     */
    protected void hideNonThisWeek() {
        mTimetableView.isShowNotCurWeek(false).updateView();
    }

    /**
     * 显示非本周课程
     * 修改了内容的显示，所以必须更新全部（性能不高）
     * 建议：在初始化时设置该属性
     */
    protected void showNonThisWeek() {
        mTimetableView.isShowNotCurWeek(true).updateView();
    }

    /**
     * 设置侧边栏最大节次，只影响侧边栏的绘制，对课程内容无影响
     *
     * @param num
     */
    protected void setMaxItem(int num) {
        mTimetableView.maxSlideItem(num).updateSlideView();
    }

    /**
     * 显示时间
     * 设置侧边栏构建监听，TimeSlideAdapter是控件实现的可显示时间的侧边栏
     */
    protected void showTime() {
        String[] times = new String[]{"8:00", "9:00", "10:10", "11:00", "15:00", "16:00",
                "17:00", "18:00", "19:30", "20:30", "21:30", "22:30"};
        OnSlideBuildAdapter listener = (OnSlideBuildAdapter) mTimetableView.onSlideBuildListener();
        listener.setTimes(times)
                .setTimeTextColor(Color.BLACK.getValue());
        mTimetableView.updateSlideView();
    }

    /**
     * 隐藏时间
     * 将侧边栏监听置Null后，会默认使用默认的构建方法，即不显示时间
     * 只修改了侧边栏的属性，所以只更新侧边栏即可（性能高），没有必要更新全部（性能低）
     */
    protected void hideTime() {
        mTimetableView.callback((ISchedule.OnSlideBuildListener) null);
        mTimetableView.updateSlideView();
    }

    /**
     * 显示WeekView
     */
    protected void showWeekView() {
        mTimetableView.setShowWeekView(true);
        mWeekView.isShow(true);
    }

    /**
     * 隐藏WeekView
     */
    protected void hideWeekView() {
        mTimetableView.setShowWeekView(false);
        mWeekView.isShow(false);
    }

    /**
     * 设置月份宽度
     */
    private void setMonthWidth() {
        mTimetableView.monthWidthDp(100).updateView();
    }

    /**
     * 设置月份宽度,默认80vp
     */
    private void resetMonthWidth() {
        mTimetableView.monthWidthDp(80).updateView();
    }

    /**
     * 隐藏周末
     */
    private void hideWeekends() {
        mTimetableView.isShowWeekends(false).updateView();
    }

    /**
     * 显示周末
     */
    private void showWeekends() {
        mTimetableView.isShowWeekends(true).updateView();
    }
}
